#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 10010 * 2, INF = 0x3f3f3f3f;
int n;
int e[N], ne[N], h[N], w[N], idx;
int d1[N], d2[N], p[N], up[N];
bool is_left[N];
// 对于一个指定的节点，该节点有两种情况：
// 1. 往下走 2. 往上走
// 可以先dfs求解每个节点往下走的最大值，即用子节点的数据更新父节点
// 然后再dfs更新往上走的最大值，用父节点的数据更新子节点

void add(int a, int b, int c)
{
    e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}

// 用子节点更新父节点，前序遍历
int dfs_d(int u, int father)
{
    d1[u] = d2[u] = -INF;
    for (int i = h[u]; ~i; i = ne[i])
    {
        int j = e[i];
        if (j == father) continue;
        int d = dfs_d(j, u) + w[i];
        if (d >= d1[u])
            d2[u] = d1[u], d1[u] = d, p[u] = j;
        else if (d > d2[u])
            d2[u] = d;
    }
    if (d1[u] == d2[u] && d1[u] == -INF)
        is_left[u] = true, d1[u] = d2[u] = 0;
    return d1[u];
}

// up[u]: 从u节点向上走的最长距离
// 用父节点更新子节点，后序遍历
void dfs_u(int u, int father)
{
    for (int i = h[u]; ~i; i = ne[i])
    {
        int j = e[i];
        if (j == father) continue;
        // up[u]: 向上走的最长距离
        // d1[u]: 除向上走以外的最长距离
        // d2[u]: 除向上走以为的次长距离
        if (p[u] != j)
            up[j] = max(up[u], d1[u]) + w[i];
        else
            up[j] = max(up[u], d2[u]) + w[i];

        dfs_u(j, u);
    }
}

int main()
{
    memset(h, -1, sizeof h);
    cin >> n;
    for (int i = 0; i < n - 1; ++i)
    {
        int a, b, c;
        cin >> a >> b >> c;
        add(a, b, c), add(b, a, c);
    }
    // 更新每个节点向下走的最大值
    dfs_d(1, -1);
    // 更新每个节点向上走的最大值
    dfs_u(1, -1);
    int res = d1[1];
    for (int i = 2; i <= n; i++)
        if (is_left[i]) res = min(res, up[i]);
        else res = min(res, max(d1[i], up[i]));
    cout << res << endl;
    return 0;
}